<template>
    <div class="page">
        <p>力导向图</p>
        <div id="container"></div>
    </div>
</template>
<script>
import * as d3 from "d3"
export default {
    methods: {
        draw() {
            //预先定义好，svg的大小，以及 在svg内部作画的时候 各种padding的值
            let svgWidth = 600,
                svgHeight = 400
            //使用d3创建一个svg元素
            let svg = (this.svg = d3.select("#container").append("svg"))
            //设置svg的宽高
            svg.attr("width", svgWidth).attr("height", svgHeight)
            // .attr("viewBox", [-300,-200, 600, 400]);
            let nodes = [
                    { name: "鼎域前沿" },
                    { name: "韦力快购" },
                    { name: "移花互动" },
                    { name: "德车车" },
                    { name: "紫金诚" }
                ],
                edges = [
                    { source: "鼎域前沿", target: "韦力快购" },
                    { source: "韦力快购", target: "移花互动" },
                    { source: "鼎域前沿", target: "移花互动" },
                    { source: "德车车", target: "韦力快购" },
                    { source: "鼎域前沿", target: "紫金诚" }
                ],
                forceLyout = d3
                    .forceSimulation(nodes)
                    .force("charge", d3.forceManyBody().strength(-400))
                    .force("center", d3.forceCenter(300, 200))
                    .force(
                        "link",
                        d3
                            .forceLink(edges)
                            .distance(90)
                            .id(d => d.name)
                    )
                    .force("x", d3.forceX())
                    .force("y", d3.forceY()),
                colors = d3.schemeCategory10
            let lines = svg
                .selectAll(".forceLine")
                .data(edges)
                .enter()
                .append("line")
                .attr("class", "forceLine")
                .attr("stroke", "#000")
                .attr("stroke-width", "1px")
            let circles = svg
                .selectAll(".forceCircle")
                .data(nodes)
                .enter()
                .append("circle")
                .attr("class", "forceCircle")
                .attr("r", 20)
                .attr("fill", (d, i) => colors[i])
                .call(
                    d3
                        .drag()
                        .on("drag", (event, d) => {
                            d.fx = this.clamp(event.x, 0, svgWidth)
                            d.fy = this.clamp(event.y, 0, svgHeight)
                            forceLyout.alpha(1).restart()
                        })
                        // .on("end", (event, d) => {
                        //     delete d.fx
                        //     delete d.fy
                        //     forceLyout.alpha(1).restart()
                        // })
                )
            let texts = svg
                .selectAll(".forceText")
                .data(nodes)
                .enter()
                .append("text")
                .attr("class", "forceText")
                .attr("x", d => d.x)
                .attr("y", d => d.y)
                .attr("dy", ".3em")
                .text(d => d.name)
            forceLyout.on("tick", () => {
                lines.attr("x1", d => d.source.x)
                lines.attr("y1", d => d.source.y)
                lines.attr("x2", d => d.target.x)
                lines.attr("y2", d => d.target.y)
                circles.attr("cx", d => d.x)
                circles.attr("cy", d => d.y)
                texts.attr("x", d => d.x)
                texts.attr("y", d => d.y)
            })
            d3.dragDisable(window)
        },
        clamp(x, lo, hi) {
            return x < lo ? lo : x > hi ? hi : x
        }
    },
    mounted() {
        this.draw()
    }
}
</script>
